#include "precomp.h"

namespace Tmpl {

float Ray3f::IntersectBox(const AABB3f& bbox) const
{
	const Vec3f r( 1.0f / mDir.x, 1.0f / mDir.y, 1.0f / mDir.z );
	float tmin = 0.001f, tmax = mLength;
	for ( int axis = 0; axis < 3; ++axis ) 
	{
		const float t0 = (bbox.min[axis] - mOrigin[axis]) * r[axis];
		const float t1 = (bbox.max[axis] - mOrigin[axis]) * r[axis];
		const float nr = (t0 < t1) ? t0 : t1, fr = (t0 < t1) ? t1 : t0;
		tmin = (tmin < nr) ? nr : tmin, tmax = (fr <  tmax) ? fr : tmax;
	}
	if (tmin <= tmax)
		return tmin;
	else
		return -1.0f;
}

float Ray2f::IntersectBox(const AABB2f& bbox) const
{
	const Vec2f r( 1.0f / mDir.x, 1.0f / mDir.y );
	float tmin = 0.001f, tmax = mLength;
	for ( int axis = 0; axis < 2; ++axis ) 
	{
		const float t0 = (bbox.min[axis] - mOrigin[axis]) * r[axis];
		const float t1 = (bbox.max[axis] - mOrigin[axis]) * r[axis];
		const float nr = (t0 < t1) ? t0 : t1, fr = (t0 < t1) ? t1 : t0;
		tmin = (tmin < nr) ? nr : tmin, tmax = (fr <  tmax) ? fr : tmax;
	}
	if (tmin <= tmax)
		return tmin;
	else
		return -1.0f;
}

float Ray3f::IntersectSphere(const Vec3f pos, const float radius) const 
{
	float radius2 = radius * radius;
	Vec3f v = mOrigin - pos;
	float b = -v.Dot(mDir);
	float det = (b * b) - v.Dot(v) + radius2;
	if (det > 0.0f)
	{
		det = sqrtf( det );
		float i1 = b - det;
		float i2 = b + det;
		if (i2 > 0.0f)
		{
			if (i1 < 0.0f) 
			{
				if (i2 < mLength) return i2;
			}
			else
			{
				if (i1 < mLength) return i1;
			}
		}
	}
	return -1.0f;
}

float Ray2f::IntersectSphere(const Vec2f pos, const float radius) const 
{
	float radius2 = radius * radius;
	Vec2f v = mOrigin - pos;
	float b = -v.Dot(mDir);
	float det = (b * b) - v.Dot(v) + radius2;
	if (det > 0.0f)
	{
		det = sqrtf( det );
		float i1 = b - det;
		float i2 = b + det;
		if (i2 > 0.0f)
		{
			if (i1 < 0.0f) 
			{
				if (i2 < mLength) return i2;
			}
			else
			{
				if (i1 < mLength) return i1;
			}
		}
	}
	return -1.0f;
}



} // Namespace